#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
4399账号批量注册工具 - GUI线程
处理后台任务的线程类 - 支持多线程并行处理
"""

import os
import time
import threading
from concurrent.futures import ThreadPoolExecutor, as_completed
from queue import Queue
from PySide2.QtCore import QThread, Signal, QMutex

from register_bot import Register4399Bot
from config import Config


class RegisterThread(QThread):
    """多线程注册线程 - 支持8个线程并行注册"""
    # 信号定义
    progress_updated = Signal(int)  # 进度更新信号
    log_updated = Signal(str)  # 日志更新信号
    registration_complete = Signal(bool, str)  # 注册完成信号
    account_registered = Signal(str, str)  # 账号注册成功信号

    def __init__(self, count, real_name=None, id_card=None, max_workers=8, username_prefix="dai", uuid_length=10):
        """初始化

        Args:
            count: 要注册的账号数量
            real_name: 真实姓名
            id_card: 身份证号
            max_workers: 最大线程数，默认8个
            username_prefix: 账号名前缀，默认"dai"
            uuid_length: UUID随机数位数，默认10位
        """
        super().__init__()
        self.count = count
        self.real_name = real_name
        self.id_card = id_card
        self.max_workers = max_workers
        self.username_prefix = username_prefix
        self.uuid_length = uuid_length
        self.is_running = True
        self.config = Config()
        self.completed_count = 0
        self.success_count = 0
        self.file_mutex = QMutex()  # 文件写入互斥锁
        self.executor = None  # 线程池执行器

    def register_single_account_worker(self, task_id):
        """单个账号注册工作函数"""
        bot = None
        try:
            self.log_updated.emit(f"🚀 线程 {task_id} 开始注册账号...")

            # 创建独立的注册机器人实例
            bot = Register4399Bot()

            # 设置身份信息
            if self.real_name and self.id_card:
                bot.set_identity_info(self.real_name, self.id_card)
            else:
                return False, "缺少身份信息"

            # 初始化浏览器 - 这是关键步骤！
            self.log_updated.emit(f"🔧 线程 {task_id} 正在初始化浏览器...")
            if not bot.setup_driver():
                self.log_updated.emit(f"❌ 线程 {task_id} 浏览器初始化失败")
                return False, "浏览器初始化失败"

            self.log_updated.emit(f"✅ 线程 {task_id} 浏览器初始化成功")

            # 注册账号，传递用户名配置
            result = bot.register_single_account(username_prefix=self.username_prefix, uuid_length=self.uuid_length)

            if result and len(result) == 2 and result[0] and result[1]:
                username, password = result

                # 线程安全地保存账号信息
                self.file_mutex.lock()
                try:
                    self.account_registered.emit(username, password)
                    self.success_count += 1
                    self.log_updated.emit(f"✅ 线程 {task_id} 注册成功: {username}")
                finally:
                    self.file_mutex.unlock()

                bot.close_driver()
                return True, username
            else:
                self.log_updated.emit(f"❌ 线程 {task_id} 注册失败")
                bot.close_driver()
                return False, "注册失败"

        except Exception as e:
            self.log_updated.emit(f"❌ 线程 {task_id} 出错: {str(e)}")
            if bot:
                try:
                    bot.close_driver()
                except:
                    pass
            return False, str(e)

    def run(self):
        """多线程注册运行"""
        try:
            self.log_updated.emit(f"🚀 启动多线程注册，使用 {self.max_workers} 个线程...")

            # 检查身份信息
            if not self.real_name or not self.id_card:
                self.log_updated.emit("❌ 缺少身份信息，无法注册")
                self.registration_complete.emit(False, "缺少身份信息")
                return

            self.log_updated.emit(f"📋 计划注册 {self.count} 个账号")
            self.log_updated.emit(f"👤 使用身份信息: {self.real_name}")

            # 使用线程池执行注册任务
            self.executor = ThreadPoolExecutor(max_workers=self.max_workers)
            try:
                # 提交所有注册任务
                future_to_task = {
                    self.executor.submit(self.register_single_account_worker, i+1): i+1
                    for i in range(self.count)
                }

                # 处理完成的任务
                for future in as_completed(future_to_task):
                    if not self.is_running:
                        self.log_updated.emit("🛑 注册过程被用户中断，正在停止所有线程...")
                        # 取消所有未完成的任务
                        for f in future_to_task:
                            if not f.done():
                                f.cancel()
                        self.executor.shutdown(wait=False)
                        self.registration_complete.emit(False, "用户中断")
                        return

                    task_id = future_to_task[future]
                    self.completed_count += 1

                    try:
                        success, message = future.result()
                        if success:
                            self.log_updated.emit(f"🎉 任务 {task_id} 完成: {message}")
                        else:
                            self.log_updated.emit(f"❌ 任务 {task_id} 失败: {message}")
                    except Exception as e:
                        self.log_updated.emit(f"❌ 任务 {task_id} 异常: {str(e)}")

                    # 更新进度
                    progress = int((self.completed_count / self.count) * 100)
                    self.progress_updated.emit(progress)
            finally:
                if self.executor:
                    self.executor.shutdown(wait=False)

            # 完成
            self.log_updated.emit(f"🎉 多线程注册完成！成功: {self.success_count}/{self.count}")
            self.registration_complete.emit(True, f"注册完成，成功率: {self.success_count/self.count*100:.1f}%")

        except Exception as e:
            self.log_updated.emit(f"❌ 多线程注册出错: {str(e)}")
            self.registration_complete.emit(False, str(e))
    
    def stop(self):
        """停止线程和所有工作线程"""
        self.log_updated.emit("🛑 正在停止注册线程...")
        self.is_running = False

        # 如果线程池存在，立即关闭
        if self.executor:
            try:
                self.log_updated.emit("🛑 正在关闭线程池...")
                self.executor.shutdown(wait=False)
                self.log_updated.emit("✅ 线程池已关闭")
            except Exception as e:
                self.log_updated.emit(f"⚠️ 关闭线程池时出错: {str(e)}")






